package com.txz.web.controller.common;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.txz.common.config.TxzConfig;
import com.txz.common.constant.Constants;
import com.txz.common.core.domain.AjaxResult;
import com.txz.common.utils.StringUtils;
import com.txz.common.utils.file.FileUploadUtils;
import com.txz.common.utils.file.FileUtils;
import com.txz.framework.config.ServerConfig;

/**
 * 通用请求处理
 * 
 * @author txz
 */
@RestController
@RequestMapping("/common")
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;

    private static final String FILE_DELIMETER = ",";

    /**
     * 通用下载请求
     * 
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.checkAllowDownload(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = TxzConfig.getDownloadPath() + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = TxzConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 通用上传请求（多个）
     */
    @PostMapping("/uploads")
    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = TxzConfig.getUploadPath();
            List<String> urls = new ArrayList<String>();
            List<String> fileNames = new ArrayList<String>();
            List<String> newFileNames = new ArrayList<String>();
            List<String> originalFilenames = new ArrayList<String>();
            for (MultipartFile file : files)
            {
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = serverConfig.getUrl() + fileName;
                urls.add(url);
                fileNames.add(fileName);
                newFileNames.add(FileUtils.getName(fileName));
                originalFilenames.add(file.getOriginalFilename());
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 调试方法：列出images目录中的文件
     */
    @GetMapping("/debug/files")
    public AjaxResult debugImageFiles() {
        try {
            String uploadPath = TxzConfig.getUploadPath();
            File imagesDir = new File(uploadPath + "/images");
            
            if (!imagesDir.exists() || !imagesDir.isDirectory()) {
                return AjaxResult.error("images目录不存在");
            }
            
            File[] files = imagesDir.listFiles();
            if (files == null || files.length == 0) {
                return AjaxResult.success("images目录为空");
            }
            
            StringBuilder sb = new StringBuilder();
            sb.append("images目录中的文件:\n");
            
            for (File file : files) {
                sb.append(file.getName()).append(" (").append(file.length()).append(" bytes)\n");
            }
            
            return AjaxResult.success(sb.toString());
        } catch (Exception e) {
            return AjaxResult.error("获取文件列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取图片目录列表
     */
    @GetMapping("/images/dirs")
    public AjaxResult getImageDirs() {
        try {
            String uploadPath = TxzConfig.getUploadPath();
            List<Map<String, Object>> dirs = new ArrayList<>();
            
            // 检查images目录是否存在
            File imagesDir = new File(uploadPath + "/images");
            
            // 如果目录不存在，尝试创建
            if (!imagesDir.exists()) {
                boolean created = imagesDir.mkdirs();
            }
            
            if (imagesDir.exists() && imagesDir.isDirectory()) {
                // 列出目录中的所有文件
                File[] files = imagesDir.listFiles();
                
                if (files != null && files.length > 0) {
                    for (int i = 0; i < Math.min(files.length, 5); i++) {
                        File file = files[i];
                    }
                }
                
                Map<String, Object> dirInfo = new HashMap<>();
                dirInfo.put("name", "图片库");
                dirInfo.put("path", Constants.RESOURCE_PREFIX + "/images");
                
                // 统计该目录下的图片数量
                int imageCount = countImagesInDir(imagesDir);
                dirInfo.put("imageCount", imageCount);
                
                dirs.add(dirInfo);
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("baseDir", Constants.RESOURCE_PREFIX);
            result.put("dirs", dirs);
            
            return AjaxResult.success(result);
        } catch (Exception e) {
            return AjaxResult.error("获取目录列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 统计目录下的图片数量
     */
    private int countImagesInDir(File dir) {
        int count = 0;
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    String name = file.getName().toLowerCase();
                    if (name.endsWith(".jpg") || name.endsWith(".jpeg") || 
                        name.endsWith(".png") || name.endsWith(".gif") || 
                        name.endsWith(".bmp") || name.endsWith(".webp")) {
                        count++;
                    }
                } else if (file.isDirectory()) {
                    count += countImagesInDir(file);
                }
            }
        }
        return count;
    }

    /**
     * 获取图片列表
     */
    @GetMapping("/images/list")
    public AjaxResult getImageList(
        @RequestParam(defaultValue = "") String dir,
        @RequestParam(defaultValue = "1") Integer page,
        @RequestParam(defaultValue = "20") Integer pageSize,
        @RequestParam(defaultValue = "") String search) {
        
        try {
            // 将虚拟路径转换为物理路径
            String physicalPath = convertVirtualPathToPhysical(dir);
            File targetDir = new File(physicalPath);
            
            if (!targetDir.exists() || !targetDir.isDirectory()) {
                return AjaxResult.error("目录不存在");
            }
            
            // 先列出目录中的所有文件
            File[] allFiles = targetDir.listFiles();            
            if (allFiles != null && allFiles.length > 0) {
                for (int i = 0; i < Math.min(allFiles.length, 5); i++) {
                    File file = allFiles[i];
                }
            }
            
            // 过滤出图片文件
            List<File> imageFileList = new ArrayList<>();
            if (allFiles != null) {
                for (File file : allFiles) {
                    if (file.isFile()) {
                        String name = file.getName();
                        String extension = "";
                        int lastDotIndex = name.lastIndexOf(".");
                        if (lastDotIndex > 0 && lastDotIndex < name.length() - 1) {
                            extension = name.substring(lastDotIndex + 1).toLowerCase();
                        }
                        boolean isImage = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "webp").contains(extension);
                        if (isImage) {
                            imageFileList.add(file);
                        }
                    }
                }
            }
            
            File[] imageFiles = imageFileList.toArray(new File[0]);
            if (imageFiles.length > 0) {
                for (int i = 0; i < Math.min(imageFiles.length, 5); i++) {
                    File file = imageFiles[i];
                }
            }
            
            // 处理搜索条件
            List<File> filteredFiles = new ArrayList<>();
            if (StringUtils.isNotEmpty(search)) {
                for (File file : imageFiles) {
                    if (file.getName().toLowerCase().contains(search.toLowerCase())) {
                        filteredFiles.add(file);
                    }
                }
            } else {
                filteredFiles = Arrays.asList(imageFiles);
            }
            
            // 分页处理
            int total = filteredFiles.size();
            int fromIndex = (page - 1) * pageSize;
            int toIndex = Math.min(fromIndex + pageSize, total);
            List<File> pagedFiles = filteredFiles.subList(fromIndex, toIndex);
            
            // 构建返回数据
            List<Map<String, Object>> images = new ArrayList<>();
            for (File file : pagedFiles) {
                Map<String, Object> imageInfo = new HashMap<>();
                imageInfo.put("id", file.getName());
                imageInfo.put("name", file.getName());
                
                // 构建URL
                String relativePath = file.getAbsolutePath().substring(TxzConfig.getUploadPath().length());
                String url = Constants.RESOURCE_PREFIX + relativePath.replace("\\", "/");
                imageInfo.put("url", url);
                
                imageInfo.put("size", file.length());
                
                // 获取文件创建时间
                BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
                imageInfo.put("createTime", attrs.creationTime().toString());
                
                images.add(imageInfo);
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("total", total);
            result.put("images", images);
            result.put("currentDir", dir);
            
            // 获取父目录
            String parentDir = getParentDir(dir);
            result.put("parentDir", parentDir);
            
            return AjaxResult.success(result);
        } catch (Exception e) {
            return AjaxResult.error("获取图片列表失败：" + e.getMessage());
        }
    }

    /**
     * 将虚拟路径转换为物理路径
     */
    private String convertVirtualPathToPhysical(String virtualPath) {
        if (StringUtils.isEmpty(virtualPath)) {
            return TxzConfig.getUploadPath() + "/images";
        }
        
        if (virtualPath.startsWith(Constants.RESOURCE_PREFIX + "/images")) {
            String relativePath = virtualPath.substring((Constants.RESOURCE_PREFIX + "/images").length());
            return TxzConfig.getUploadPath() + "/images" + relativePath.replace("/", File.separator);
        }
        
        return TxzConfig.getUploadPath() + "/images";
    }

    /**
     * 获取父目录
     */
    private String getParentDir(String dir) {
        if (StringUtils.isEmpty(dir) || dir.equals(Constants.RESOURCE_PREFIX + "/images")) {
            return "";
        }
        
        int lastSlash = dir.lastIndexOf("/");
        if (lastSlash > 0) {
            return dir.substring(0, lastSlash);
        }
        
        return Constants.RESOURCE_PREFIX + "/images";
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        try
        {
            if (!FileUtils.checkAllowDownload(resource))
            {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = TxzConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + FileUtils.stripPrefix(resource);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }
}
